﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApp9
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int[,] map = new int[24, 32] {
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
        {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        };

        private Mario mario;                //玩家角色，见Mario.cs
        private Ellipse marioDisplayCtrl;   //代表玩家的圆形显示控件
        private DispatcherTimer timer;      //主时间片定时器

        public MainWindow()
        {
            InitializeComponent();

            //初始化主时间片
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(40); //25FPS
            timer.Tick += Timer_Tick;
            timer.Start();

            //首次绘制场景
            DrawMap();

            //初始化测试数据
            mario = new Mario();
            mario.X = 7;
            mario.Y = 18;

            //更新玩家显示
            DrawMario();
        }

        //此函数每秒调用40次，所有逻辑均在此完成
        private void Timer_Tick(object? sender, EventArgs e)
        {
            //处理操作
            if (Keyboard.IsKeyDown(Key.Left)) 
            {
                if (map[(int)mario.Y, (int)(mario.X) - 1] == 0)
                {
                    mario.Move(Direction.Left);
                }
            }
            if (Keyboard.IsKeyDown(Key.Right))
            {
                if (map[(int)mario.Y, (int)(mario.X) + 1] == 0)
                {
                    mario.Move(Direction.Right);
                }
                
            }
            if (Keyboard.IsKeyDown(Key.Up))
            {
                if (mario.HeightToJump == 0 && (map[(int)mario.Y + 1, (int)mario.X] != 0 || map[(int)mario.Y + 1, (int)mario.X + 1] != 0))
                {
                    mario.HeightToJump = 6;
                }
            }

            //更新mario的状态
            if (mario.HeightToJump > 0 && map[(int)(mario.Y-0.01f), (int)(mario.X + 0.99f)] == 0 && map[(int)(mario.Y - 0.01f), (int)(mario.X)] == 0)
            {
                mario.Y -= 0.25; 
                mario.HeightToJump -= 0.25;
            }
            else
            {
                mario.HeightToJump = 0;
                //下落判断
                if (map[(int)(mario.Y + 1),(int)(mario.X + 0.99f)] == 0 && map[(int)mario.Y+1, (int)mario.X] == 0)
                {
                    mario.Y += 0.25;
                }
                

            }

            //重绘
            //暂时只绘制角色
            DrawMario();
        }

        /// <summary>
        /// 绘制场景，注意只有有墙的位置才创建对应的rect
        /// </summary>
        private void DrawMap()
        {
            for (int i = 0; i < 24; i++)
            {
                for (int j = 0; j < 32; j++)
                {
                    if (map[i,j] == 1)
                    {
                        Rectangle rect = new Rectangle();
                        rect.Fill = new SolidColorBrush(Colors.Gray);
                        rect.Width = 24;
                        rect.Height = 24;
                        rect.SetValue(Canvas.LeftProperty, j * 25.0);
                        rect.SetValue(Canvas.TopProperty, i * 25.0);
                        mainCanvas.Children.Add(rect);
                    }
                }
            }
        }

        //绘制/重绘玩家角色
        private void DrawMario()
        {
            //仅首次，初始化
            if (marioDisplayCtrl == null)
            {
                marioDisplayCtrl = new Ellipse();
                marioDisplayCtrl.Fill = new SolidColorBrush(Colors.Red);
                marioDisplayCtrl.Width = 24;
                marioDisplayCtrl.Height = 24;
                marioCanvas.Children.Add(marioDisplayCtrl);
            }

            //更新位置
            marioDisplayCtrl.SetValue(Canvas.LeftProperty, mario.X * 25.0);
            marioDisplayCtrl.SetValue(Canvas.TopProperty, mario.Y * 25.0);

        }
    }
}
